/*
 * memory/section.c
 *
 * Copyright (C) 2019 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <memory.h>

void memory_cleanup(object_t *object)
{
    // TODO: Not implemented
}

memory_section_t *memory_create_zero_backed_section(const char *name, page_num_t num_pages)
{
    memory_section_t *section = malloc(sizeof(memory_section_t));
    if (!section) return NULL;

    section->header.name = strdup(name);
    if (name && !section->header.name) return NULL;

    section->header.type = OBJECT_MEMORY;
    section->backing = MEMORY_ZERO_BACKED_SECTION;
    section->num_pages = num_pages;

    if (create_object(&section->header) != ERR_SUCCESS)
    {
        free(section);
        section = NULL;
    }

    return section;
}

memory_section_t *memory_create_file_backed_section(const char *name, file_instance_t *file, page_num_t num_pages)
{
    memory_section_t *section = malloc(sizeof(memory_section_t));
    if (!section) return NULL;

    section->header.name = name ? strdup(name) : NULL;
    if (name && !section->header.name) return NULL;

    section->header.type = OBJECT_MEMORY;
    section->backing = MEMORY_FILE_BACKED_SECTION;
    section->num_pages = num_pages;
    reference(&file->header);
    section->file = file;

    if (create_object(&section->header) != ERR_SUCCESS)
    {
        dereference(&file->header);
        if (name) free(section->header.name);
        free(section);
        section = NULL;
    }

    return section;
}

memory_section_t *memory_create_physical_backed_section(const char *name, const area_t *area)
{
    memory_section_t *section = malloc(sizeof(memory_section_t));
    if (!section) return NULL;

    section->header.name = name ? strdup(name) : NULL;
    if (name && !section->header.name) return NULL;

    section->header.type = OBJECT_MEMORY;
    section->backing = MEMORY_PHYSICAL_BACKED_SECTION;
    section->pages = area->pages;
    section->num_pages = area->count;

    if (create_object(&section->header) != ERR_SUCCESS)
    {
        if (name) free(section->header.name);
        free(section);
        section = NULL;
    }

    return section;
}

sysret_t syscall_create_memory_section(const char *name, handle_t file, size_t size, dword_t flags, handle_t *handle)
{
    return ERR_NOSYSCALL;
}

sysret_t syscall_open_memory_section(const char *name, handle_t *handle)
{
    return ERR_NOSYSCALL;
}

sysret_t syscall_map_memory_section(handle_t process, handle_t section, void **address, qword_t offset, size_t size, dword_t flags)
{
    return ERR_NOSYSCALL;
}

sysret_t syscall_flush_memory_section(handle_t process, void *address)
{
    return ERR_NOSYSCALL;
}
